#include "DataStructure/Input/Element/CQUAD4Data.h"

#include "DataStructure/Common/Out.h"
#include "DataStructure/Common/Validation.h"

using namespace SG::DataStructure;

bool FEM::CQUAD4Data::IsVariationalThickness () const
{
    for (const double& iNode : m_ti)  // NOLINT(readability-use-anyofallof)
    {
        if (iNode > 1.0e-9)
        {
            return true;
        }
    }

    return false;
}

/** @brief 获得单元节点厚度
 * @param tp pshell 中的厚度值
 * @param [out] 节点厚度值，可以传入一个 长度为 4 的数组
 */
void FEM::CQUAD4Data::GetThickness (SG::DataStructure::Common::Real tp, SG::DataStructure::Common::Real* tNodes) const
{
    for (const double& iNode : m_ti)
    {
        if (iNode > 1.0e-9)
        {
            *tNodes = iNode;
            // m_ti[iNode]为相对厚度
            if (1 == m_tflag)
            {
                *tNodes = iNode * tp;
            }
        }
        else
        {
            *tNodes = tp;
        }
        ++tNodes;
    }
}

std::vector<Common::Real> FEM::CQUAD4Data::ComputeShellThick (bool /*isComposite*/, SG::DataStructure::Common::Real tp) const
{
    std::vector<Common::Real> nodeThick{tp, tp, tp, tp};
    bool variableT = this -> IsVariationalThickness ();
    if (variableT)
    {
        this -> GetThickness (tp, _OUT nodeThick.data());
    }

    return nodeThick;
}

/// @brief 判断两个CQUAD4Data是否相等
bool SG::DataStructure::FEM::operator== (const CQUAD4Data& a, const CQUAD4Data& b)
{
    if (a.m_id != b.m_id)
    {
        return false;
    }
    if (a.m_pId != b.m_pId)
    {
        return false;
    }
    for (int i = 0; i < 4; ++i)
    {
        if (a.m_g[i] != b.m_g[i])
        {
            return false;
        }
    }
    if (a.m_domainId != b.m_domainId)
    {
        return false;
    }
    if (!SG::DataStructure::Common::isNear (a.m_theta, b.m_theta))
    {
        return false;
    }
    if (!SG::DataStructure::Common::isNear (a.m_zoffs, b.m_zoffs))
    {
        return false;
    }
    if (a.m_tflag != b.m_tflag)
    {
        return false;
    }
    for (int i = 0; i < 4; ++i)
    {
        if (!SG::DataStructure::Common::isNear (a.m_ti[i], b.m_ti[i]))
        {
            return false;
        }
    }
    if (a.m_mcId != b.m_mcId)
    {
        return false;  // NOLINT(readability-simplify-boolean-expr)
    }
    return true;
}